package com.yl.order.ui;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.net.RetrofitUtils;
import com.net.device.DeviceApiRepository;
import com.net.yl.ApiRepository;
import com.net.yl.entity.ResponseEntity;
import com.yl.common.ui.BaseActivity;
import com.yl.common.utils.LogUtil;
import com.yl.order.App;
import com.yl.order.BuildConfig;
import com.yl.order.Constants;
import com.yl.order.CrashHandler;
import com.yl.order.R;
import com.yl.order.db.DbManage;
import com.yl.order.entity.SyncDeviceWrap;
import com.yl.order.helper.DataSyncHelper;
import com.yl.order.helper.MqttServiceHelper;
import com.yl.order.helper.SmallApkHelper;
import com.yl.order.model.ConfigModel;
import com.yl.order.model.OrderModel;
import com.yl.order.ui.dialog.ConfirmDialogFragment;
import com.yl.order.ui.dialog.EditDialogFragment;
import com.yl.order.ui.dialog.NetInfoDialogFragment;
import com.yl.order.ui.fragment.MainOrderFragment;
import com.yl.order.utils.SPUtils;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends BaseActivity implements View.OnClickListener {

    private final int REQUEST_SN_CODE = 1001;
    private final int REQUEST_PERMISSION_CODE = 1000;
    private final String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_COARSE_LOCATION,};

    private int[] syncCommands;
    private boolean mqttConnectStatus = false;
    private Disposable checkDisposable;

    private MainOrderFragment orderFragment;

    private View tagPrinterView;
    private View receiptPrinterView;
    private View deviceView;

    private final Handler checkHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            Schedulers.io().scheduleDirect(() -> {
                String ip = SPUtils.getString(Constants.SP_SERVER_IP, null);
                boolean success;
                try {
                    success = InetAddress.getByName(ip).isReachable(2000);
                } catch (IOException e) {
                    success = false;
                }
                final boolean result = success;
                AndroidSchedulers.mainThread().scheduleDirect(() -> {
                    if (result) {
                        DeviceApiRepository.getInstance().init("http://" + ip + ":9100");
                        deviceView.setSelected(true);
                    } else {
                        DeviceApiRepository.getInstance().init(null);
                        deviceView.setSelected(false);
                    }
                });
            });
            checkHandler.sendEmptyMessageDelayed(0, 5000);
            return false;
        }
    });

    private final BroadcastReceiver networkReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Constants.ACTION_PRINTER_CONNECT_STATUS.equals(intent.getAction())) {
                boolean tagConnectStatus = intent.getBooleanExtra("tag_status", false);
                boolean receiptConnectStatus = intent.getBooleanExtra("receipt_status", false);
                tagPrinterView.setSelected(tagConnectStatus);
                receiptPrinterView.setSelected(receiptConnectStatus);
                return;
            }
            if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
                return;
            }
            refreshNetStatus();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        tagPrinterView = findViewById(R.id.tag_printer);
        receiptPrinterView = findViewById(R.id.receipt_printer);
        tagPrinterView.setOnClickListener(this);
        receiptPrinterView.setOnClickListener(this);
        deviceView = findViewById(R.id.device);
        deviceView.setOnClickListener(this);

        // 监听网络状态变化的广播
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(Constants.ACTION_PRINTER_CONNECT_STATUS);
        registerReceiver(networkReceiver, filter);

        // 启动打印服务
        Intent serviceIntent = new Intent("com.cjx.print.service.BackgroundService");
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(serviceIntent);
            } else {
                startService(serviceIntent);
            }
        } catch (Exception e) {
            // 处理后台启动限制异常
            System.out.println("系统限制从后台启动服务,无法启动服务: " + e.getMessage());
        }

        findViewById(R.id.net_status).setOnClickListener(this);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
        } else {
            afterPermissionCheck();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (checkDisposable != null) {
            checkDisposable.dispose();
            checkDisposable = null;
        }
        checkHandler.removeMessages(0);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.net_status) {
            NetInfoDialogFragment.newInstance()
                    .setServerConnect(mqttConnectStatus)
                    .show(getSupportFragmentManager(), "net");
        } else if (id == R.id.device) {
            EditDialogFragment.newInstance()
                    .setTitle(getString(R.string.dialog_device_title))
                    .setHint(getString(R.string.dialog_device_placeholder))
                    .setValue(SPUtils.getString(Constants.SP_SERVER_IP, null))
                    .setConfirmCallback(ip -> {
                        SPUtils.putString(Constants.SP_SERVER_IP, ip);
                        DeviceApiRepository.getInstance().init("http://" + ip + ":9100");
                        deviceView.setSelected(true);
                        checkHandler.sendEmptyMessageDelayed(0, 5000);
                        return true;
                    }).show(getSupportFragmentManager(), "server_ip");
        } else if (id == R.id.tag_printer || id == R.id.receipt_printer) {
            try {
                Intent intent = new Intent("com.yl.print.main");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
            } catch (Exception e) {

            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION_CODE) {
            boolean flagt = false;
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] != 0) {
                    flagt = true;
                    break;
                }
            }
            if (flagt) {//授权失败
                finish();
            } else {
                afterPermissionCheck();
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_SN_CODE && resultCode == RESULT_OK) {
            init();
        } else {
            finish();
        }
    }

    private void afterPermissionCheck() {
        // app版本
        TextView appVersionView = findViewById(R.id.app_version);
        if (BuildConfig.DEBUG) {
            appVersionView.setTextColor(Color.RED);
            appVersionView.setText(BuildConfig.VERSION_NAME + "-dev");
        } else {
            appVersionView.setText(BuildConfig.VERSION_NAME);
        }

        String ip = SPUtils.getString(Constants.SP_SERVER_IP, null);
        if (!TextUtils.isEmpty(ip)) {
            checkDisposable = Schedulers.io().scheduleDirect(() -> {
                boolean success;
                try {
                    success = InetAddress.getByName(ip).isReachable(2000);
                } catch (IOException e) {
                    success = false;
                }
                final boolean result = success;
                AndroidSchedulers.mainThread().scheduleDirect(() -> {
                    checkDisposable = null;
                    if (result) {
                        DeviceApiRepository.getInstance().init("http://" + ip + ":9100");
                        deviceView.setSelected(true);
                    }
                    checkHandler.sendEmptyMessageDelayed(0, 5000);
                });
            });
        }

        ApiRepository.getInstance().init(BuildConfig.YL_URL);

        LiveEventBus.config().autoClear(true).enableLogger(false);
        SmallApkHelper.initAndCheckSmallApk(this);
        LogUtil.getInstance().initLogFile(this, Constants.FILE_LOG_RUN_DIR);
        DbManage.getInstance().init(this, Constants.FILE_DB_DIR);
        CrashHandler.getsInstance().init();
        RetrofitUtils.getInstance().setLogCallback(((tag, message) -> LogUtil.getInstance().log(tag, message)));

        SyncDeviceWrap wrap = ConfigModel.getSyncDeviceWrap();
        if (wrap != null) {
            App.app.activateInfo = wrap.activateInfo;
            App.app.storeInfo = wrap.storeInfo;
            App.app.favicon = wrap.favicon;
        }
        if (App.app.activateInfo == null) {
            App.app.activateInfo = ConfigModel.getActivate();
        }
        if (App.app.activateInfo == null) {
            DataSyncHelper.getInstance().resetSn();
            Intent intent = new Intent(this, SnSettingActivity.class);
            startActivityForResult(intent, REQUEST_SN_CODE);
        } else {
            init();
        }

        // 获取当天流水号起始位置
        OrderModel.initTodaySerialNumber();
    }

    private void init() {
        // 先监听
        registerSysEvent();

        if (TextUtils.isEmpty(App.app.activateInfo.getPwd())) {
            afterSync();
            return;
        }
        ApiRepository.getInstance().bindDevice(App.app.activateInfo.getSn(), App.app.activateInfo.getPwd());
        DataSyncHelper.getInstance().syncProductCheck();
    }

    private void registerSysEvent() {
        LiveEventBus.get(Constants.BUS_SYNC_PRODUCT_RESPONSE).observe(this, o -> {
            ResponseEntity<?> response = (ResponseEntity<?>) o;
            if (response != null && !response.isSuccess()) {
                LogUtil.getInstance().log("MAIN", " 同步产品失败:" + response.message);
                showToast(String.format(getString(R.string.main_sync_failed_format), response.message));
            } else {
                LiveEventBus.get(Constants.BUS_PRODUCT_GROUP_UPDATE).post(1);
            }
            afterSync();
            // 设置门店
            if (App.app.storeInfo != null) {
                TextView storeView = findViewById(R.id.store);
                String storeValue = App.app.storeInfo.getName() + " " + App.app.storeInfo.getStoreCode();
                storeView.setText(storeValue);
            }
        });
        LiveEventBus.get(Constants.BUS_SYNC_DATA_ACTION).observe(this, o -> {
            if (o == null) {
                return;
            }
            syncCommands = (int[]) o;
            syncProductByCommand();
        });
    }

    private void afterSync() {
        MqttServiceHelper.getInstance().init(connect -> mqttConnectStatus = connect);

        // 设置时间
        setTime();

        // 设置星期
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int min = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        long delay = (86400 - hour * 3600 - min * 60 - second) * 1000L;
        setWeek(delay);

        // 设置设备编号
        TextView numberView = findViewById(R.id.number);
        numberView.setText(String.format(getString(R.string.main_device_id_format),
                App.app.activateInfo.getSn()));

        // 设置门店
        TextView storeView = findViewById(R.id.store);
        if (App.app.storeInfo != null) {
            StringBuilder storeBuilder = new StringBuilder(50);
            storeBuilder.append(App.app.storeInfo.getName());
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                if (storeBuilder.length() > 0) {
                    storeBuilder.append("-");
                }
                storeBuilder.append(App.app.storeInfo.getStoreCode());
            }
            storeView.setText(storeBuilder.toString());
        } else {
            storeView.setText(R.string.main_store_name);
        }
        ImageView logoView = findViewById(R.id.logo);
        if (!TextUtils.isEmpty(App.app.favicon)) {
            Glide.with(logoView)
                    .asBitmap()
                    .load(BuildConfig.IMAGE_URL + App.app.favicon)
                    .placeholder(R.drawable.logo)
                    .into(logoView);
        } else {
            File file = new File(Constants.FILE_DIR + "/logo.png");
            if (file.exists()) {
                Glide.with(logoView)
                        .load(file)
                        .placeholder(R.drawable.logo)
                        .into(logoView);
            } else {
                logoView.setImageResource(R.drawable.logo);
            }
        }

        initFragmentView();

        // 删除过期的订单信息
        deleteHistory();

        // 关闭开机进度
        View progressView = findViewById(R.id.progress_tip);
        ((ViewGroup) progressView.getParent()).removeView(progressView);
    }

    private void deleteHistory() {
        long lastTime = System.currentTimeMillis() - 90 * 86400000L;
        OrderModel.deleteHistory(lastTime);
        LogUtil.getInstance().deleteHistory(Constants.FILE_LOG_RUN_DIR, lastTime);
        LogUtil.getInstance().deleteHistory(Constants.FILE_LOG_CRASH_DIR, lastTime);
    }

    private void setTime() {
        Timer timer = new Timer(true);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(() -> {
                    String dayTime = Constants.DATE_TIME_FORMAT.format(new Date());
                    ((TextView) findViewById(R.id.time)).setText(dayTime);
                });
            }
        }, 0, 1000);
    }

    private void setWeek(long delay) {

        TextView weekView = findViewById(R.id.week);
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        switch (dayOfWeek) {
            case 1:
                weekView.setText(R.string.main_week_7);
                break;
            case 2:
                weekView.setText(R.string.main_week_1);
                break;
            case 3:
                weekView.setText(R.string.main_week_2);
                break;
            case 4:
                weekView.setText(R.string.main_week_3);
                break;
            case 5:
                weekView.setText(R.string.main_week_4);
                break;
            case 6:
                weekView.setText(R.string.main_week_5);
                break;
            case 7:
                weekView.setText(R.string.main_week_6);
                break;
        }
        weekView.postDelayed(() -> setWeek(86400000), delay);
    }

    private void initFragmentView() {

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        orderFragment = MainOrderFragment.newInstance();
        transaction.add(R.id.fragment_container, orderFragment);

        transaction.commitNow();
    }

    private void syncProductByCommand() {
        if (syncCommands == null) {
            return;
        }
        boolean check = false;
        for (int code : syncCommands) {
            if (code == MqttServiceHelper.CMD_SYNC_PRODUCT) {
                check = true;
                break;
            }
        }
        if (!check) {
            return;
        }
        ConfirmDialogFragment.newInstance()
                .setCanceled(false)
                .setTitle(getString(R.string.dialog_sync_tip))
                .setDescribe(getString(R.string.dialog_sync_product_describe))
                .setConfirmCallback(i -> {
                    showToast(getString(R.string.main_syncing));
                    DataSyncHelper.getInstance().resetProductCache();
                    DataSyncHelper.getInstance().syncProductCheck();
                    syncCommands = null;
                })
                .setCancelButton(getString(R.string.button_sync_after), i -> {
                    DataSyncHelper.getInstance().resetProductCache();
                    syncCommands = null;
                })
                .show(getSupportFragmentManager(), "confirm_dialog");
    }

    private void refreshNetStatus() {
        ConnectivityManager netManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = netManager.getActiveNetworkInfo();
        ImageView statusIconView = findViewById(R.id.net_status);
        if (info == null || !info.isAvailable()) {
            statusIconView.setImageResource(R.drawable.vector_net_disconnect);
        } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {
            statusIconView.setImageResource(R.drawable.vector_wifi_on);
        } else {
            statusIconView.setImageResource(R.drawable.vector_ethernet);
        }

    }

}